<template>
	<button @click="onclick" @touchstart="touchstart" @touchend="touchend" @longpress="emits('longpress', $event)"
		@touchcancel="touchcancel" @touchmove="emits('touchmove', $event)"
		@getphonenumber="emits('getphonenumber', $event)" @error="emits('error', $event)"
		@opensetting="emits('opensetting', $event)" @launchapp="emits('launchapp', $event)"
		@contact="emits('contact', $event)" @chooseavatar="emits('chooseavatar', $event)" :form-type="props.formType"
		:openType="props.openType" :appParameter="props.appParameter" :sessionFrom="props.sessionFrom"
		:sendMessageTitle="props.sendMessageTitle" :sendMessagePath="props.sendMessagePath"
		:sendMessageImg="props.sendMessageImg" :sendMessageCard="props.sendMessageCard" :loading="_load"
		:disabled="_disabled" :group-id="props.groupId" :guild-id="props.guildId" :public-id="props.publicId"
		:hover-start-time="10000000" hover-stop-propagation :class="[
      'button alipay flex flex-row flex-row-center-center',
      isclickOn && !_disabled && !_load ? props.hoverClass + ' bhover' : '',
      !_disabled && !_load ? 'webpc' : '',
      _load || _disabled ? 'opacity-8' : '',
      !isDisabledRoundAndriod ? `round-${btnSizeObj.round}` : '',
      customClass,
    ]" :style="[
      {
        marginLeft: _margin[0] + 'rpx',
        marginTop: _margin[1] + 'rpx',
        marginRight: _margin[2] + 'rpx',
        marginBottom: _margin[3] + 'rpx',
        paddingLeft: _padding[0] + 'rpx',
        paddingTop: _padding[1] + 'rpx',
        paddingRight: _padding[2] + 'rpx',
        paddingBottom: _padding[3] + 'rpx',
      },
      {
        height: btnSizeObj.h + props.unit,
        fontSize: btnSizeObj.fontSize + props.unit,
        color: textColor,
        lineHeight: btnSizeObj.h + props.unit,
      },
      btnSizeObj.w && !props.block ? { width: btnSizeObj.w + props.unit } : '',
      tmcomputed.borderCss,
      _bgcolor,
      !_transprent && _shadow > 0 && !props.text ? tmcomputed.shadowColor : '',
      customCSSStyle,
    ]">
		<slot>
			<tm-icon :lineHeight="btnSizeObj.fontSize * 0.9" v-if="_icon && !_load" :userInteractionEnabled="false"
				:color="_fontColor" :_class="_label ? 'pr-10' : ''" :unit="props.unit"
				:fontSize="btnSizeObj.fontSize * 0.9" :name="_icon"></tm-icon>
			<!-- #ifdef APP-NVUE -->
			<zh-text :color="props.fontColor" :font-size="btnSizeObj.fontSize" :unit="props.unit" :label="_label"
				_class="text-weight-b"></zh-text>
			<!-- #endif -->
			<!-- #ifndef APP-NVUE -->
			{{ _label }}
			<!-- #endif -->
		</slot>
	</button>
</template>

<script lang="ts" setup>
	/**
 * 按钮
 * @description 属性与原生按钮一致，对于微信登录授权进行了便捷封装。
 * @slot default 默认插槽。
 */
	import { btnSize } from './interface';
	import { computed, PropType, ref, getCurrentInstance, provide } from 'vue';

	import { cssstyle } from '@/tool/lib/interface';
	import { custom_props, computedTheme, computedClass, computedStyle, computedDark } from '@/tool/lib/minxs';
	import theme from '@/tool/theme/theme';
	import systemConfigStore from '@/store/modules/systemConfigStore';
	const store = systemConfigStore();

	/**
	 * 事件说明
	 * @description 事件属性与原生 一 致
	 * @links 见官网：https://uniapp.dcloud.io/component/button.html
	 */
	const emits = defineEmits<{
		(e : 'click', event : Event | TouchEvent) : void;
		(e : 'touchstart', event : Event | TouchEvent) : void;
		(e : 'touchmove', event : Event | TouchEvent) : void;
		(e : 'touchcancel', event : Event | TouchEvent) : void;
		(e : 'touchend', event : Event | TouchEvent) : void;
		(e : 'tap', event : Event | TouchEvent) : void;
		(e : 'longpress', event : Event | TouchEvent) : void;
		(e : 'getphonenumber', event : any) : void;
		(e : 'getUserInfo', event : any) : void;
		(e : 'getUserProfile', event : any) : void;
		(e : 'error', event : any) : void;
		(e : 'opensetting', event : any) : void;
		(e : 'launchapp', event : any) : void;
		(e : 'contact', event : any) : void;
		(e : 'chooseavatar', event : any) : void;
	}>();
	const isnvue = ref(false);
	// #ifdef APP-NVUE
	isnvue.value = true;
	// #endif
	const proxy = getCurrentInstance()?.proxy ?? null;
	const props = defineProps({
		...custom_props,
		transprent: {
			type: Boolean,
			default: false,
		},
		followTheme: {
			type: Boolean,
			default: true,
		},
		hoverClass: {
			type: String,
			default: 'opacity-7',
		},
		/**
		 * mini,small,normal,middle,large
		 */
		size: {
			type: String as PropType<btnSize>,
			default: 'normal',
		},
		fontSize: {
			type: Number,
			default: 0,
		},
		fontColor: {
			type: String,
			default: '',
		},
		margin: {
			type: Array as PropType<Array<number>>,
			default: () => [0, 16],
		},
		padding: {
			type: Array as PropType<Array<number>>,
			default: () => [0, 0],
		},
		//不是同层背景，默认是同层，为false
		//如果输入框表单与tmshee在同一层下。他们的黑白暗黑背景色是相同的。为了区分这个问题，需要单独指示，以便区分背景同层。
		//主意：它只在黑和白之间的色系才起作用，其它颜色下不起作用。
		noLevel: {
			type: Boolean,
			default: false,
		},
		shadow: {
			type: Number,
			default: 0,
		},
		width: {
			type: Number,
			default: 0,
		},
		height: {
			type: Number,
			default: 0,
		},
		//如果为true，采用块状flex布局，自动宽和高度。
		block: {
			type: Boolean,
			default: false,
		},
		round: {
			type: Number,
			default: 0,
		},
		loading: {
			type: Boolean,
			default: false,
		},
		disabled: {
			type: Boolean,
			default: false,
		},
		//提供时，点击后会中转到对应页面。
		url: {
			type: String,
			default: '',
		},
		label: {
			type: String,
			default: '',
		},
		icon: {
			type: String,
			default: '',
		},
		/**
		 * submit,reset zh-form中使用。
		 */
		formType: {
			type: String as PropType<'submit' | 'reset' | 'filterCancel' | 'filterConfirm'>,
			default: '',
		},
		//开放能力
		openType: {
			type: String,
			default: '',
		},
		//打开 APP 时，向 APP 传递的参数，open-type=launchApp时有效
		appParameter: {
			type: String,
			default: '',
		},
		sessionFrom: {
			type: String,
			default: '',
		},
		sendMessageTitle: {
			type: String,
			default: '',
		},
		sendMessagePath: {
			type: String,
			default: '',
		},
		sendMessageImg: {
			type: String,
			default: '',
		},
		sendMessageCard: {
			type: String,
			default: '',
		},
		groupId: {
			type: String,
			default: '',
		},
		guildId: {
			type: String,
			default: '',
		},
		publicId: {
			type: String,
			default: '',
		},
		unit: {
			type: String,
			default: 'rpx',
		},
		darkBgColor: {
			type: String,
			default: '',
		},
		/**禁用后的主题色 */
		disabledColor: {
			type: String,
			default: 'grey-1',
		},
	});

	/** -----------form专有------------ */
	const formtype = computed(() => props.formType);
	//父级方法。
	let FormParent : any = null;
	let FilterParent : any = null;
	if (formtype.value == 'reset' || formtype.value == 'submit') {
		FormParent = proxy?.$parent;
		while (FormParent) {
			if (FormParent?.zhFormComnameId == 'zhFormId' || !FormParent) {
				break;
			} else {
				FormParent = FormParent?.$parent ?? undefined;
			}
		}
	}
	//过滤器菜单 专用属性.
	if (formtype.value == 'filterCancel' || formtype.value == 'filterConfirm') {
		FilterParent = proxy?.$parent;
		while (FilterParent) {
			if (FilterParent?.FilterMenu == 'FilterMenu' || !FilterParent) {
				break;
			} else {
				FilterParent = FilterParent?.$parent ?? undefined;
			}
		}
	}
	/** -----------end------------ */
	const _noLevel = computed(() => props.noLevel);
	//是否暗黑模式。
	const isDark = computed(() => computedDark(props, tmcfg.value));
	// 设置响应式主题文字色。
	let textColor = computed(() => {
		if (theme.isCssColor(_fontColor.value)) return _fontColor.value;
		if (!props.fontColor) return tmcomputed.value.textColor;
		return theme.getColor(props.fontColor).value;
	});
	//自定义样式：
	const customCSSStyle = computed(() => {
		return {
			// height: btnSizeObj.value.h + props.unit,
			...computedStyle(props),
			// fontSize:props.fontSize,
			// color:textColor,
			// border: "0px solid rgba(0, 0, 0, 0)",
			// background: "rgba(0, 0, 0, 0)",
			// borderRadius: "0px",
		};
	});
	//自定类
	const customClass = computed(() => computedClass(props));
	// 设置响应式全局组件库配置表。
	const tmcfg = computed(() => store);
	//计算主题
	const _shadow = computed(() => props.shadow || (store.themeConfig?.component?.button?.shadow ?? 0));

	const tmcomputed = computed<cssstyle>(() => {
		let nprops = { ...props, shadow: _shadow.value };
		if (_disabled.value) {
			nprops.color = props.disabledColor;
		}
		return computedTheme({ ...nprops }, isDark.value, tmcfg.value);
	});

	const isclickOn = ref(false);
	const _load = computed(() => props.loading);
	const _disabled = computed(() => props.disabled);
	const _label = computed(() => props.label);
	const _icon = computed(() => props.icon);
	const _isBorder = computed(() => {
		if (props.outlined && props.border == 0) return 1;
		if (props.border > 0) return props.border;
		return 0;
	});
	const sizeObj = computed(() => {
		let ptest = {
			block: { w: 0, h: 80, fontSize: 28, round: 3 },
			mini: { w: 88, h: 36, fontSize: 20, round: 3 },
			small: { w: 120, h: 56, fontSize: 22, round: 3 },
			normal: { w: 220, h: 80, fontSize: 28, round: 3 },
			middle: { w: 300, h: 80, fontSize: 30, round: 3 },
			large: { w: 375, h: 80, fontSize: 32, round: 3 },
		};
		if (props.unit == 'px') {
			let key : 'block' | 'mini' | 'small' | 'normal' | 'middle' | 'large' = 'block';
			let key2 : 'w' | 'h' | 'fontSize' | 'round' = 'w';
			for (key in ptest) {
				for (key2 in ptest[key]) {
					ptest[key][key2] = uni.upx2px(ptest[key][key2]);
				}
			}
		}
		return ptest;
	});
	const btnSizeObj = computed(() => {
		let fontSize = props.fontSize || 0;

		if (props.block) {
			return {
				w: 0,
				h: props.height || sizeObj.value.block.h,
				fontSize: fontSize || sizeObj.value.block.fontSize,
				round: props.round == -1 ? 0 : props.round || (store.themeConfig?.component?.button?.round ?? 0) || sizeObj.value.normal.round,
			};
		}
		return {
			w: props.width || sizeObj.value[props.size].w,
			h: props.height || sizeObj.value[props.size].h,
			fontSize: fontSize || sizeObj.value[props.size].fontSize,
			round: props.round == -1 ? 0 : props.round || (store.themeConfig?.component?.button?.round ?? 0) || sizeObj.value[props.size].round,
		};
	});
	const _fontColor = computed(() => props.fontColor);
	const _transprent = computed(() => props.transprent);
	/** 数组是左，上，右，下顺序。 */
	const _margin = computed(() => {
		if (props.margin.length == 1) return [props.margin[0], props.margin[0], props.margin[0], props.margin[0]];
		if (props.margin.length == 2) return [props.margin[0], props.margin[1], props.margin[0], props.margin[1]];
		if (props.margin.length == 3) return [props.margin[0], props.margin[1], props.margin[2], 0];
		if (props.margin.length == 4) return [props.margin[0], props.margin[1], props.margin[2], props.margin[3]];
		return [0, 0, 0, 0];
	});
	const _padding = computed(() => {
		if (props.padding.length == 1) return [props.padding[0], props.padding[0], props.padding[0], props.padding[0]];
		if (props.padding.length == 2) return [props.padding[0], props.padding[1], props.padding[0], props.padding[1]];
		if (props.padding.length == 3) return [props.padding[0], props.padding[1], props.padding[2], 0];
		if (props.padding.length == 4) return [props.padding[0], props.padding[1], props.padding[2], props.padding[3]];
		return [0, 0, 0, 0];
	});

	const _bgcolor = computed(() => {
		if (_transprent.value === true) return `background-color:rgba(255,255,255,0);`;
		if (props.darkBgColor !== '' && isDark.value === true) {
			return `background-color:${props.darkBgColor};`;
		}
		if (props.linearColor.length == 2) {
			return { 'background-image': `linear-gradient(${tmcomputed.value.linearDirectionStr},${props.linearColor[0]},${props.linearColor[1]})` };
		}
		if (tmcomputed.value.gradientColor?.length == 2) {
			return tmcomputed.value.backgroundColorCss;
		}
		if (_noLevel.value && tmcomputed.value.isBlackAndWhite === true && isDark.value === true) {
			return `background-color: ${tmcomputed.value.inputcolor}`;
		}
		return `background-color: ${tmcomputed.value.backgroundColor}`;
	});

	function touchstart(e : Event) {
		isclickOn.value = true;
		emits('touchstart', e);
	}
	function touchend(e : Event) {
		isclickOn.value = false;
		emits('touchend', e);
	}
	function touchcancel(e : Event) {
		isclickOn.value = false;
		emits('touchcancel', e)
	}
	function onclick(e : Event) {
		if (FormParent != null && typeof FormParent != 'undefined' && formtype.value && !props.loading) {
			FormParent[formtype.value]();
		}
		if (FilterParent != null && typeof FilterParent != 'undefined' && formtype.value && !props.loading) {
			FilterParent[formtype.value]();
		}
		// if button loading , not handle click
		if (props.loading) return;
		emits('click', e);
		if (props.url !== '' && typeof props.url === 'string') {
			let url = props.url;
			if (url[0] !== '/') url = '/' + url;
			uni.navigateTo({
				url: url,
			});
			return;
		}
		if (props.openType == 'getUserInfo' || props.openType == 'getUserProfile') {
			// #ifdef MP-WEIXIN
			uni.getUserProfile({
				desc: '用于完善会员资料',
				success: function (userProfile) {
					if (userProfile.errMsg != 'getUserProfile:ok') {
						uni.showToast({
							title: userProfile.errMsg,
							icon: 'error',
							mask: true,
						});
						return;
					}
					emits('getUserInfo', userProfile);
					emits('getUserProfile', userProfile);
				},
				fail: (error) => {
					console.log(error);
					uni.showToast({
						icon: 'none',
						title: typeof error == 'object' ? error.errMsg : error,
					});
				},
			});
			console.warn(
				"微信小程序已收回‘getUserProfile’以及‘getUserInfo’权限，请使用open-type='chooseAvatar'使用@chooseavatar回调，详见《微信小程序用户头像昵称获取规则调整公告》https://developers.weixin.qq.com/community/develop/doc/00022c683e8a80b29bed2142b56c01"
			);
			// #endif
		}
	}

	provide('appTextColor', textColor);
</script>

<style scoped>
	.button {
		/* background: rgba(0, 0, 0, 0); */
		/* border: 0px solid rgba(0, 0, 0, 0); */
		padding: 0px;
		/* border-radius: 0px; */
	}

	.disabled {
		opacity: 0.6 !important;
	}

	.buttonHover {
		/* background: rgba(0, 0, 0, 0); */
	}

	.bhover {
		opacity: 0.7;
	}

	/* #ifdef H5 */
	/*.webpc:hover{
  cursor: pointer;
	opacity: 0.7;

}*/
	/* #endif */
	/* #ifndef APP-NVUE */
	/*.bhover:hover{
	opacity: 0.7;
}*/
	.button::after {
		background: transparent !important;
		background-color: transparent !important;
		border: none !important;
		border-radius: 0px !important;
	}

	/* #endif */
	/* #ifdef MP */
	.button.alipay {
		transition: opacity 0.7s;
	}

	/* #endif */
</style>